package cn.monkey.chat.server.connect.chat.state;

import cn.monkey.chat.server.connect.chat.state.group.ChatGroupFactory;
import cn.monkey.chat.server.connect.chat.state.group.ChatRepository;
import cn.monkey.chat.server.connect.chat.state.scheduler.ReactiveChatSchedulerManager;
import cn.monkey.chat.server.connect.util.Timer;
import cn.monkey.state.core.reactive.ReactiveStateGroupFactory;
import cn.monkey.state.core.reactive.ReactiveStateGroupPool;
import cn.monkey.state.core.reactive.SimpleReactiveStateGroupPool;
import cn.monkey.state.scheduler.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

@Configuration
public class StateConfig {

    @Bean
    ChatRepository chatRepository() {
        return new SimpleTestChatRepository();
    }

    @Bean
    Scheduler reactiveScheduler() {
        return Schedulers.newSingle("reactive-scheduler");
    }

    @Bean
    Timer timer() {
        return new Timer() {
        };
    }

    @Bean
    ReactiveStateGroupFactory reactiveStateGroupFactory(Timer timer,
                                                        ChatRepository chatRepository) {
        return new ChatGroupFactory(timer, chatRepository);
    }


    @Bean
    SimpleReactiveStateGroupPool stateGroupPool(ReactiveStateGroupFactory reactiveStateGroupFactory) {
        return new SimpleReactiveStateGroupPool(reactiveStateGroupFactory);
    }

    @Bean
    StateGroupSchedulerFactory stateGroupSchedulerFactory() {
        StateGroupSchedulerFactoryConfig stateGroupSchedulerFactoryConfig = StateGroupSchedulerFactoryConfig.newBuilder().build();
        return new SimpleStateGroupSchedulerFactory(stateGroupSchedulerFactoryConfig);
    }

    @Bean
    EventPublishSchedulerFactory eventPublishSchedulerFactory() {
        return new RingBufferEventPublishSchedulerFactory();
    }

    @Bean
    SchedulerManager schedulerManager(Scheduler reactiveScheduler,
                                      ReactiveStateGroupPool stateGroupPool,
                                      StateGroupSchedulerFactory stateGroupSchedulerFactory,
                                      EventPublishSchedulerFactory eventPublishSchedulerFactory) {
        SchedulerManagerConfig managerConfig = SchedulerManagerConfig.newBuilder().build();
        return new ReactiveChatSchedulerManager(reactiveScheduler, stateGroupPool, stateGroupSchedulerFactory, eventPublishSchedulerFactory, managerConfig);
    }
}
